﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using NLog;

namespace BookSourceVerification.handlers;

public class HandlerChain
{
    private readonly LinkedList<IHandler<JObject>> _handlers = new();
    private Logger _logger = LogManager.GetCurrentClassLogger();

    /// <summary>
    ///
    /// </summary>
    /// <param name="node"></param>
    /// <returns>true表示节点可用，false表示节点不可用</returns>
    public async Task<bool> DoChain(JObject node)
    {
        HandlerResult result = new();
        foreach (var handler in _handlers)
        {
            await handler.Handler(node, result);
            if (!result.Flag)
            {
                return false;
            }

            if (result.Final)
            {
                break;
            }
        }
        return true;
    }

    public void ReleaseHandlerResources()
    {
        foreach (var handler in _handlers)
        {
            handler.AfterHandler();
        }
    }

    public IHandler<JObject>? ReplaceHandler(Type handler, IHandler<JObject> newHandler)
    {
        var target = GetHandler(handler);
        if (target == null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return null;
        }

        var node = this._handlers.Find(target);
        if (node is null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return null;
        }

        this._handlers.AddAfter(node,
            new LinkedListNode<IHandler<JObject>>(newHandler));
        RemoveHandler(target);
        return target;
    }

    public void AddFirstHandler(IHandler<JObject> handler)
    {
        this._handlers.AddFirst(handler);
    }

    public void AddLastHandler(IHandler<JObject> handler)
    {
        this._handlers.AddLast(handler);
    }

    public void RemoveFirstHandler()
    {
        this._handlers.RemoveFirst();
    }

    public void RemoveLastHandler()
    {
        this._handlers.RemoveLast();
    }

    public void RemoveHandler(IHandler<JObject> node)
    {
        this._handlers.Remove(node);
    }

    public void RemoveHandler(Type type)
    {
        var target = GetHandler(type);
        if (target == null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return;
        }

        this._handlers.Remove(target);
    }

    public void AddHandlerBefore(Type targetHandler, IHandler<JObject> newHandler)
    {
        var target = GetHandler(targetHandler);
        if (target == null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return;
        }

        var node = this._handlers.Find(target);
        if (node is null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return;
        }

        this._handlers.AddBefore(node,
            new LinkedListNode<IHandler<JObject>>(newHandler));
    }

    public void AddHandlerAfter(Type targetHandler, IHandler<JObject> newHandler)
    {
        var target = GetHandler(targetHandler);
        if (target == null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return;
        }

        var node = this._handlers.Find(target);
        if (node is null)
        {
            _logger.Error("没有发现任何验证书源的处理器，请联系开发人员！");
            return;
        }

        this._handlers.AddAfter(node,
            new LinkedListNode<IHandler<JObject>>(newHandler));
    }

    public IHandler<JObject>? GetHandler(Type handlerType)
    {
        IHandler<JObject>? target = null;
        foreach (var handler in this._handlers)
        {
            if (handler.GetType() == handlerType)
            {
                target = handler;
                break;
            }
        }

        return target;
    }
}